import pymysql
from db import config


class MyModel:
    '''单表信息操作'''
    tab_name = None  # 表名
    dbconnect = None  # 数据库连接对象
    cursor = None  # 游标对象
    prikey = None  # 主键字段名
    fields = []  # 表的所有字段名

    def __init__(self, table, config=config):
        ''' 构造方法，初始化表名、通过配置参数连接数据库、创建游标对象等'''
        try:
            # 指定当前表名
            self.tab_name = table
            # 指定MySQL数据库信息
            self.dbconnect = pymysql.connect(host=config.HOST, user=config.USER, password=config.PASSWD,
                                             db=config.DBNAME, charset="utf8")
            # 使用cursor()方法创建游标 pymysql.cursors.DictCursor参数让查询结果以字典方式返回
            self.cursor = self.dbconnect.cursor(pymysql.cursors.DictCursor)
            # 调用内部方法加载当前表的所有字段名
            self.__loadFields()
        except Exception as err:
            print("数据库操作对象初始化失败，原因：%s" % err)

    def __loadFields(self):
        '''加载当前表的字段信息,内部私有方法'''
        sql = "SHOW COLUMNS FROM %s" % (self.tab_name)  # desc 表名
        self.cursor.execute(sql)
        dlist = self.cursor.fetchall()
        # print("{}".format(dlist))
        # 遍历所有字段信息
        for v in dlist:
            # 收集每个字段名称
            self.fields.append(v['Field'])
            # 判断并收集表的主键名称
            if v['Key'] == 'PRI':
                self.prikey = v['Field']

    def selectAll(self):
        '''查询表中所有数据'''
        try:
            sql = "select * from %s " % (self.tab_name)
            self.cursor.execute(sql)
            return self.cursor.fetchall()
        except Exception as err:
            print("查询表数据错误 原因是 %s" % err)
            return []
    def selectByPriKey(self, prikey):
        '''通过主键查询数据'''
        try:
            sql = "select * from %s where %s=%s " % (self.tab_name, self.prikey, prikey)
            self.cursor.execute(sql)
            return self.cursor.fetchone()
        except Exception as err:
            print("查询表数据错误 原因是 %s" % err)
            return  []

    def select(self,where=[],order=None,limit=None):
        '''通过where，order limit查询数据'''
        try:
            sql="select * from %s"%(self.tab_name)
            #判断并封装where搜索条件
            if isinstance(where,list) and len(where)>0:
                sql +=" where "+" and ".join(where)
            # 判断并封装order排序条件
            if order is not None:
                sql += " order by " + str(order)
            # 判断并封装limit条件
            if limit is not None:
                sql += " limit " + str(limit)
            #print("sql=%s"%sql)
            self.cursor.execute(sql)
            return self.cursor.fetchall()
        except Exception as err:
            print("查询表数据错误 原因是 %s" % err)
            return []

    def insert(self, data={}):
        '''插入数据'''
        try:
            # 组装sql语句
            keys = []
            values = []
            for k, v in data.items():
                if k in self.fields:
                    keys.append(k)
                    values.append(v)

            sql1 = "insert into %s (%s) values(%s)" % (self.tab_name, ','.join(keys), ','.join(['%s'] * len(values)))
            #print("sql1=%s"%sql1)
            self.cursor.execute(sql1,tuple(values))
            # 指定参数，并执行sql添加
            self.dbconnect.commit()
            return self.cursor.lastrowid
        except Exception as err:
            print("插入数据错误 原因是 %s" % err)
            return []

    def update(self,data={}):
        '''通过主键更新数据,data字典存放要更新的数据'''
        try:
            # 组装sql语句
            values = []
            for k, v in data.items():
                if (k in self.fields) and (k != self.prikey):
                    values.append("%s='%s'" % (k, v))
            sql = "update %s set %s where %s='%s'" % (self.tab_name, ','.join(values), self.prikey, data.get(self.prikey))
            #print(sql)
            # 指定参数，并执行修改sql
            self.cursor.execute(sql)
            # 事务提交
            self.dbconnect.commit()
            # 返回数据条数或影响行数
            return self.cursor.rowcount
        except Exception as err:
            print("SQL修改执行错误，原因：%s" % err)
            return 0

    def delete(self, id=0):
        '''接收参数值id并执行删除对应的数据信息'''
        try:
            # 组装sql语句
            sql = "delete from %s where %s='%s'" % (self.tab_name, self.prikey, id)
            print(sql)
            # 指定参数，并执行修改sql
            self.cursor.execute(sql)
            # 事务提交
            self.dbconnect.commit()
            # 返回数据条数或影响行数
            return self.cursor.rowcount
        except Exception as err:
            print("SQL修改执行错误，原因：%s" % err)
            return 0

    def __del__(self):
        # 关闭游标对象
        if self.cursor != None:
            self.cursor.close()
        # 关闭数据库连接
        if self.dbconnect != None:
            self.dbconnect.close()
